import React, {useEffect} from 'react';
import {Button, Checkbox, Form, Input, message, Modal, Space, Table, Tabs, Upload} from "antd";
import {ExportOutlined, InboxOutlined, UploadOutlined} from "@ant-design/icons";
import excel, {read} from "@/plugins/excel";
import CodeEditor from "@/components/CodeEditor";
import {getUUid, matchDataReplace} from "@/utils";

const {Dragger} = Upload;

interface ExcelWorkbook {
    header: string[];
    results: Record<string, any>[];
}

interface TableColumn {
    title: string;
    dataIndex: string;
    key: string;
}

interface TableRow {
    [key: string]: any;
    key: number;
}

const ExcelRead: React.FC = () => {
    const [fileVisible, setFileVisible] = React.useState<boolean>(false);
    const [matchVisible, setMatchVisible] = React.useState<boolean>(false);
    const [sqlCode, setSQLCode] = React.useState<string>('');
    const [jsonCode, setJsonCode] = React.useState<string>('');
    const [loading, setLoading] = React.useState<boolean>(false);
    const [tabItems, setTabItems] = React.useState<Array<{
        key: string;
        label: string;
        children: React.ReactNode;
    }>>([]);

    const [columnVisible, setColumnVisible] = React.useState<boolean>(false);
    const [split, setSplit] = React.useState<string>(',');
    const [splitColumn, setSplitColumn] = React.useState<string>('');


    const [columns, setColumns] = React.useState<TableColumn[]>([
        {title: "id", dataIndex: "id", key: "id"},
        {title: "name", dataIndex: "name", key: "name"},
        {title: "age", dataIndex: "age", key: "age"}
    ]);

    const [dataSource, setDataSource] = React.useState<TableRow[]>([
        {id: 1, name: 'John,Mike,Tom', age: 32, key: 1},
        {id: 2, name: 'Jen,Gan,Tarmo', age: 20, key: 2}
    ]);

    const [matchDataColumns, setMatchDataColumns] = React.useState<Record<string, any>[]>([]);
    const [matchDataSource, setMatchDataSource] = React.useState<TableRow[]>([]);
    const [targetColumns, setTargetColumns] = React.useState<Record<string, any>[]>([])  // 目标列
    const [matchColumns, setMatchColumns] = React.useState<Record<string, any>[]>([])   // 匹配列
    const [matchValue, setMatchValue] = React.useState<string>('');

    const handleReadExcel = (file: File): void => {
        setLoading(true);
        const reader = new FileReader();

        reader.onload = (e: ProgressEvent<FileReader>) => {
            const data = e.target?.result;
            if (!data) {
                message.error('读取文件失败');
                setLoading(false);
                return;
            }

            try {
                const workbook = read(data, 'binary') as ExcelWorkbook;
                console.log('Excel Data:', workbook);

                const newColumns = workbook.header.map(e => ({
                    title: e,
                    dataIndex: e,
                    key: e
                }));
                setColumns(newColumns);

                const newDataSource = workbook.results.map((row, index) => ({
                    ...row,
                    key: getUUid(),
                }));
                setDataSource(newDataSource);
                message.success('读取成功');
            } catch (error) {
                message.error('读取失败，请检查文件格式');
            } finally {
                setLoading(false);
                setFileVisible(false);
            }
        };

        reader.onerror = () => {
            message.error('读取失败');
            setLoading(false);
        };

        reader.readAsArrayBuffer(file);
    };

    const handleReadMatchExcel = (file: File): void => {
        const reader = new FileReader();

        reader.onload = (e: ProgressEvent<FileReader>) => {
            const data = e.target?.result;
            if (!data) {
                message.error('读取文件失败');
                setLoading(false);
                return;
            }

            try {
                const workbook = read(data, 'binary') as ExcelWorkbook;
                console.log('Match Excel Data:', workbook);

                const newColumns = workbook.header.map(e => ({
                    title: e,
                    dataIndex: e,
                    key: e
                }));
                setMatchDataColumns(newColumns);

                const newDataSource = workbook.results.map((row, index) => ({
                    ...row,
                    key: index + 1
                }));
                setMatchDataSource(newDataSource);
                message.success('读取成功');
            } catch (error) {
                message.error('读取失败，请检查文件格式');
            } finally {
                setLoading(false);
                setFileVisible(false);
            }
        };

        reader.onerror = () => {
            message.error('读取失败');
            setLoading(false);
        };

        reader.readAsArrayBuffer(file);
    };

    const updateTabItems = (sql: string, json: string): void => {
        setTabItems([
            {
                key: '1',
                label: 'Insert',
                children: <CodeEditor value={sql} language="sql" onChange={(v) => setSQLCode(v)}/>,
            },
            {
                key: '2',
                label: 'Json',
                children: <CodeEditor value={json} language="json" onChange={(v) => setJsonCode(v)}/>,
            },
        ]);
    };

    const handleExportExcel = () => {
        let params = {
            key: columns.map(e => e.dataIndex),
            data: dataSource,
            title: columns.map(e => e.title),
            fileName: 'export',
            autoWidth: false,
        }
        excel.export_array_to_excel(params)
    }

    const handleSplit = (): void => {
        if (!splitColumn || !split) return;

        const newDataSource: TableRow[] = [];
        dataSource.forEach((row) => {
            const columnValue = row[splitColumn];
            if (columnValue) {
                const matchColumn = String(columnValue).split(split);
                matchColumn.forEach((name) => {
                    const newRow = {...row};
                    newRow[splitColumn] = name;
                    newRow["key"] = getUUid();
                    newDataSource.push(newRow);
                });
            } else {
                newDataSource.push(row);
            }
        });
        setDataSource(newDataSource);
    };

    const handleMatch = (): void => {
        // console.log("-> targetColumns", targetColumns)
        // console.log("-> matchColumns", matchColumns);
        // console.log("-> matchValue", matchValue)
        if(!targetColumns.length || !matchColumns.length || !matchValue){
            message.error('请填写完整信息');
        }
        if(columns.map(e => e.dataIndex).includes(matchValue)){
            message.error(matchValue+'列已存在,请调整');
        }
        // 添加新的列
        setColumns(prevColumns => {
            if (prevColumns.some(column => column.dataIndex === matchValue)) {
                return prevColumns;
            }
            const newColumn = { title: matchValue, dataIndex: matchValue, key: matchValue };
            return [...prevColumns, newColumn];
        });
        const newDataSource = matchDataReplace(dataSource, matchDataSource, targetColumns, matchColumns, matchValue)
        setDataSource(newDataSource);
    };

    useEffect(() => {
        if (dataSource.length > 0) {
            const sql = `INSERT INTO table_name (${columns.map(e => e.dataIndex).join(', ')}) VALUES \n${dataSource.map((row) => {
                const rowValues = columns.map((col) => row[col.dataIndex]);
                return `('${rowValues.join("', '")}')`;
            }).join(',\n')};`;
            setSQLCode(sql);
            const jsonResult = JSON.stringify(dataSource, null, 2);
            setJsonCode(jsonResult);
            updateTabItems(sql, jsonResult);
        }
    }, [dataSource, columns]);

    return (
        <div>
            <Space style={{marginBottom: 10}}>
                <Button type="primary" icon={<UploadOutlined/>} onClick={() => {
                    setFileVisible(true);
                }}>上传Excel</Button>
                <Button danger icon={<UploadOutlined/>} onClick={() => {
                    Modal.confirm({
                        title: '清空内容',
                        content: '请确认是否要清空内容？',
                        onOk: () => {
                            setDataSource([]);
                            setColumns([]);
                        },
                    });
                }}>清空内容</Button>
                <Button color="primary" icon={<ExportOutlined />} onClick={() => {
                    Modal.confirm({
                        title: '导出Excel',
                        content: '请确认是否要导出Excel文件？',
                        onOk: () => {
                            handleExportExcel();
                        },
                    });
                }}>导出内容</Button>
                {columns.length > 0 && (
                    <>
                        <Button onClick={() => {
                            setColumnVisible(true)
                        }}>拆分列</Button>
                        <Button onClick={() => {
                            setMatchVisible(true)
                        }}>匹配文件上传</Button>
                    </>
                )}
            </Space>
            <div>
                {dataSource.length > 0 && (
                    <div>
                        <Table columns={columns} dataSource={dataSource} pagination={true}/>
                    </div>
                )}
            </div>

            <Tabs defaultActiveKey="1" type="card" items={tabItems}/>

            <Modal title="上传文件" visible={fileVisible} onCancel={() => {
                setFileVisible(false);
            }} footer={null}>
                <Dragger beforeUpload={(file) => {
                    handleReadExcel(file);
                    return false;
                }} showUploadList={false}>
                    <p className="ant-upload-drag-icon">
                        <InboxOutlined/>
                    </p>
                    <p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
                    <p className="ant-upload-hint">仅支持Excel文件</p>
                </Dragger>
                {loading && <p style={{textAlign: 'center', marginTop: 10}}>文件读取中...</p>}
            </Modal>

            <Modal title="拆分列" visible={columnVisible} onCancel={() => {
                setColumnVisible(false);
            }}
                   footer={[
                       <Button key="cancel" onClick={() => {
                           setColumnVisible(false);
                       }}>
                           取消
                       </Button>,
                       <Button key="submit" type="primary" onClick={() => {
                           handleSplit();
                           setColumnVisible(false);
                       }}>
                           确认
                       </Button>,
                   ]}
            >
                {columns.length > 0 && (
                    <Form layout="horizontal">
                        <Form.Item label="分隔符">
                            <Input
                                style={{width: 150}}
                                value={split}
                                onChange={(e) => setSplit(e.target.value)}
                                placeholder="请输入分隔符"
                            />
                        </Form.Item>
                        <Form.Item label="选择列">
                            {columns.map((column) => (
                                <Form.Item key={column.key} noStyle name={column.dataIndex}>
                                    <Checkbox
                                        value={column.dataIndex}
                                        onChange={(e) => {
                                            if (e.target.checked) {
                                                setSplitColumn(e.target.id!);
                                            } else {
                                                setSplitColumn('');
                                            }
                                        }}
                                    >
                                        {column.title}
                                    </Checkbox>
                                </Form.Item>
                            ))}
                        </Form.Item>
                    </Form>
                )}
            </Modal>

            <Modal title="上传匹配文件" visible={matchVisible} onCancel={() => {
                setMatchVisible(false);
            }} footer={[
                <Button key="cancel" onClick={() => {
                    setMatchVisible(false);
                }}>
                    取消
                </Button>,
                <Button key="clear" danger onClick={() => {
                    Modal.confirm({
                        title: '清空内容',
                        content: '请确认是否要清空内容？',
                        onOk: () => {
                            setMatchDataColumns([]);
                            setMatchColumns([]);
                            setTargetColumns([]);
                        }
                    })
                }}>
                    清空
                </Button>,
                <Button key="submit" type="primary" onClick={() => {
                    handleMatch()
                    setMatchVisible(false);
                }}>
                    确认
                </Button>,
            ]}>
                <Dragger beforeUpload={(file) => {
                    handleReadMatchExcel(file);
                    return false;
                }} showUploadList={false}>
                    <p className="ant-upload-drag-icon">
                        <InboxOutlined/>
                    </p>
                    <p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
                    <p className="ant-upload-hint">仅支持Excel文件</p>
                </Dragger>
                {matchDataColumns.length > 0 && (
                    <div>
                        <Form layout="horizontal">
                            <Form.Item label="选择目标列(key)">
                                <Checkbox.Group options={columns.map(e => e.dataIndex)} onChange={(v) => {
                                    setTargetColumns(v)
                                }}/>
                            </Form.Item>
                            <Form.Item label="选择匹配列(key)">
                                <Checkbox.Group options={matchDataColumns.map(e=>e.dataIndex)} onChange={(v) => {
                                    setMatchColumns(v)
                                }} />
                            </Form.Item>
                            <Form.Item label="选择对应值(value)">
                                {matchDataColumns.map((column) => (
                                    <Form.Item key={column.key} noStyle name={column.dataIndex}>
                                        <Checkbox
                                            value={column.dataIndex}
                                            onChange={(e) => {
                                                if (e.target.checked) {
                                                    setMatchValue(e.target.id!);
                                                } else {
                                                    setMatchValue('');
                                                }
                                            }}
                                        >
                                            {column.title}
                                        </Checkbox>
                                    </Form.Item>
                                ))}
                            </Form.Item>
                        </Form>
                    </div>
                )}
            </Modal>
        </div>
    );
};

export default ExcelRead;